package com.demo.accessibility.utils

import android.accessibilityservice.AccessibilityService
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.provider.Settings.SettingNotFoundException
import android.text.TextUtils.SimpleStringSplitter
import android.view.accessibility.AccessibilityNodeInfo
import com.demo.accessibility.app.AppStateTracker
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils

/**
AccessibilityUtils.findNoteInfoByText("应用启动管理", it)?.apply {
AccessibilityUtils.clickSelf(this.parent.getChild(0))
}
 */
object AccessibilityUtils {

    /**
     * 根据id查找节点
     * id示例：com.tencent.mm:id/cf8
     */
    fun findNoteInfoById(
        rootNode: AccessibilityNodeInfo,
        viewId: String
    ): AccessibilityNodeInfo? {
        val nodes = rootNode.findAccessibilityNodeInfosByViewId(viewId)
        if (nodes != null && nodes.isNotEmpty()) {
            return nodes[0] // 返回第一个匹配到的节点
        }
        return null
    }

    /**
     * 根据文本内容精准查找节点
     */
    fun findNoteInfoByText(
        text: MutableList<String>,
        nodeInfo: AccessibilityNodeInfo?
    ): AccessibilityNodeInfo? {
        nodeInfo?.let {
            val nodeText = it.text?.toString()
            for (str in text) {
                if (nodeText == str) {
                    return it
                }
            }
            if (it.childCount > 0) {
                for (i in 0 until it.childCount) {
                    val result = findNoteInfoByText(text, it.getChild(i))
                    if (result != null) {
                        return result
                    }
                }
            }
        }
        return null
    }

    /**
     * 根据是否包含某文本内容查找节点
     */
    fun findNoteInfoByContainsText(
        text: MutableList<String>,
        nodeInfo: AccessibilityNodeInfo?
    ): AccessibilityNodeInfo? {
        nodeInfo?.let {
            it.text?.toString()?.apply {
                for (str in text) {
                    if (this.contains(str)) {
                        return it
                    }
                }
            }
            if (it.childCount > 0) {
                for (i in 0 until it.childCount) {
                    val result = findNoteInfoByText(text, it.getChild(i))
                    if (result != null) {
                        return result
                    }
                }
            }
        }
        return null
    }

    /**
     * 根据是否以某文本内容开始 查找节点
     */
    fun findNoteInfoByStartText(
        text: MutableList<String>,
        nodeInfo: AccessibilityNodeInfo?
    ): AccessibilityNodeInfo? {
        nodeInfo?.let {
            for (str in text) {
                if (it.text != null && it.text.toString().startsWith(str)) {
                    return it
                }
            }
            if (it.childCount > 0) {
                for (i in 0 until it.childCount) {
                    val result = findNoteInfoByStartText(text, it.getChild(i))
                    if (result != null) {
                        return result
                    }
                }
            }
        }
        return null
    }

    fun findNodeInfoByStartTextAndClick(
        text: MutableList<String>,
        nodeInfo: AccessibilityNodeInfo?
    ): AccessibilityNodeInfo? {
        findNoteInfoByStartText(text, nodeInfo)?.let {
            it.performAction(AccessibilityNodeInfo.ACTION_CLICK)
            return it
        }
        return null
    }

    fun findNodeInfoAndClick(
        text: MutableList<String>,
        nodeInfo: AccessibilityNodeInfo?
    ): AccessibilityNodeInfo? {
        findNoteInfoByText(text, nodeInfo)?.let {
            it.performAction(AccessibilityNodeInfo.ACTION_CLICK)
            return it
        }
        return null
    }

    fun clickSelf(nodeInfo: AccessibilityNodeInfo) {
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
    }

    fun clickParent(nodeInfo: AccessibilityNodeInfo, upLevel: Int = 1) {
        var nodeInfoParent: AccessibilityNodeInfo? = nodeInfo
        for (i in 0 until upLevel) {
            nodeInfoParent = nodeInfoParent?.parent
        }
        nodeInfoParent?.performAction(AccessibilityNodeInfo.ACTION_CLICK)
    }

    /**
     * 回到app
     */
    fun returnApp() {
        LogUtils.e("==========isAppForeground:${AppStateTracker.instance.isAppForeground()}")
        AppStateTracker.instance.getTopActivity()?.let {
            if (!AppStateTracker.instance.isAppForeground()) {
                it.startActivity(Intent(it, it.javaClass))
            }
        } ?: kotlin.run {
            AppUtils.relaunchApp()
        }
    }

    /**
     * 返回桌面
     */
    fun goHome(context: Context) {
        val intent = Intent(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_HOME)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        context.startActivity(intent)
    }

    fun isAccessibilitySettingsOn(
        mContext: Context,
        clazz: Class<out AccessibilityService?>
    ): Boolean {
        var accessibilityEnabled = 0
        val service = mContext.packageName + "/" + clazz.canonicalName
        try {
            accessibilityEnabled = Settings.Secure.getInt(
                mContext.applicationContext.contentResolver,
                Settings.Secure.ACCESSIBILITY_ENABLED
            )
        } catch (e: SettingNotFoundException) {
            e.printStackTrace()
        }
        val mStringColonSplitter = SimpleStringSplitter(':')
        if (accessibilityEnabled == 1) {
            val settingValue = Settings.Secure.getString(
                mContext.applicationContext.contentResolver,
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
            )
            if (settingValue != null) {
                mStringColonSplitter.setString(settingValue)
                while (mStringColonSplitter.hasNext()) {
                    val accessibilityService = mStringColonSplitter.next()
                    if (accessibilityService.equals(service, ignoreCase = true)) {
                        return true
                    }
                }
            }
        }
        return false
    }
}